﻿using System;
using System.Collections.Generic;
using System.Text;
using Microsoft.Office.Interop.Outlook;
using System.Runtime.InteropServices;
using System.IO;

namespace OutlookComponent
{
    public class OutlookHelper
    {
        private static Application outlook = new Application();
        public static void CreateMailItem(string target, string subject, string body)
        {
            MailItem mail = outlook.CreateItem(OlItemType.olMailItem) as MailItem;
            mail.To = target;
            mail.Subject = subject;
            mail.Body = body;
            mail.Recipients.ResolveAll();
            mail.Display(false);
        }

        public static bool BookMeetingRoom(DateTime meetingStartTime, DateTime meetingEndTime, string subject, string body)
        {
            List<MeetingRoom> availableMeetingRooms = FindAvailableRooms(meetingStartTime, meetingEndTime);

            foreach (AddressList address in outlook.Session.AddressLists)
            {
                if (address == null || address.Name != "All Rooms")
                    continue;
                foreach (AddressEntry ae in address.AddressEntries)
                {
                    try
                    {
                        if (!IsManagedRoom(ae.Name))
                            continue;

                        string status = ae.GetFreeBusy(meetingStartTime.Date, 1, Type.Missing);
                        if (IsAvailable(status, meetingStartTime, meetingEndTime))
                        {
                            //availableMeetingRooms.Add();
                        }
                    }
                    catch (COMException exp)
                    {
                    }
                }
            }

            if (availableMeetingRooms.Count == 0)
            {
                return false;
            }
            return true;

        }

        public static AddressEntry FindMeetingRoom(string meetingRoomName)
        {
            Application outlook = new Application();
            foreach (AddressList address in outlook.Session.AddressLists)
            {
                if (address == null || address.Name != "All Rooms")
                    continue;
                foreach (AddressEntry ae in address.AddressEntries)
                {
                    try
                    {
                        if (ae.Name == meetingRoomName)
                            return ae;
                    }
                    catch (COMException exp)
                    {
                    }
                }
            }
            return null;
        }

        public static void CreateMeetingRequest(AddressEntry meetingRoomEntry, DateTime startTime, DateTime endTime, string subject, string body)
        {
            AppointmentItem meeting = outlook.CreateItem(OlItemType.olAppointmentItem) as AppointmentItem;
            meeting.Subject = subject;
            meeting.Body = body;
            meeting.Start = startTime;
            meeting.End = endTime;
            meeting.Recipients.Add(outlook.Session.CurrentUser.Name);
            var meetingRoom = meeting.Recipients.Add(meetingRoomEntry.Name);
            meetingRoom.Type = (int)OlMeetingRecipientType.olResource;
            foreach (object property in meeting.ItemProperties)
            {
                property.ToString();
            }
            //RecurrencePattern recurrencePattern = meeting.GetRecurrencePattern();
            //recurrencePattern.StartTime = startTime;
            //recurrencePattern.EndTime = endTime;
            //recurrencePattern.DayOfWeekMask = OlDaysOfWeek.olFriday | OlDaysOfWeek.olMonday;
            //recurrencePattern.Interval = 5;
            //recurrencePattern.RecurrenceType = OlRecurrenceType.olRecursWeekly;
            meeting.MeetingStatus = OlMeetingStatus.olMeeting;
            meeting.Location = meetingRoom.Name;
            meeting.BusyStatus = OlBusyStatus.olBusy;
            meeting.Recipients.ResolveAll();
            ((_AppointmentItem)meeting).Display(false);
        }

        public static List<MeetingRoom> ListAllManagedRooms()
        {
            List<MeetingRoom> rooms = new List<MeetingRoom>();

            for (int i = 0; i < 10; i++)
            {
                rooms.Add(new MeetingRoom() { Name = "MeetingRoom" + i.ToString(), Capacity = i, Address = null, HasProjector = true, RoomLocation = new MeetingRoom.Location() { Building = MeetingRoom.Building.ARCA, Floor = 2, Region = MeetingRoom.Direction.EAST } });
            }
            return rooms;

            foreach (AddressList address in outlook.Session.AddressLists)
            {
                if (address == null || address.Name != "All Rooms")
                    continue;
                foreach (AddressEntry ae in address.AddressEntries)
                {
                    try
                    {
                        if (!IsManagedRoom(ae.Name))
                            continue;
                        rooms.Add(new MeetingRoom(ae));
                    }
                    catch (COMException exp)
                    { }
                }
            }
            return rooms;
        }

        public static List<MeetingRoom> FindAvailableRooms(DateTime meetingStartTime, DateTime meetingEndTime)
        {
            List<MeetingRoom> rooms = new List<MeetingRoom>();

            foreach (AddressList address in outlook.Session.AddressLists)
            {
                if (address == null || address.Name != "All Rooms")
                    continue;
                foreach (AddressEntry ae in address.AddressEntries)
                {
                    try
                    {
                        if (!IsManagedRoom(ae.Name))
                            continue;

                        string status = ae.GetFreeBusy(meetingStartTime.Date, 1, Type.Missing);
                        if (IsAvailable(status, meetingStartTime, meetingEndTime))
                        {
                            rooms.Add(new MeetingRoom(ae));
                        }
                    }
                    catch (COMException exp)
                    {
                    }
                }
            }
            return rooms;
        }

        private static bool IsAvailable(string freeTimeSlot, DateTime startTime, DateTime endTime)
        {
            int meetingPeriodInMinutes = Convert.ToInt32(endTime.Subtract(startTime).TotalMinutes);
            int startIndex = Convert.ToInt32(startTime.TimeOfDay.TotalMinutes);
            string meetingTime = freeTimeSlot.Substring(startIndex, meetingPeriodInMinutes);
            return meetingTime.Contains("1") == false;
        }


        private static bool IsManagedRoom(string roomName)
        {
            if (string.IsNullOrEmpty(roomName))
                return false;

            // filter the meeting room which is not in arca or info building.
            if (!roomName.StartsWith("CN BJS"))
                return false;

            if (!roomName.Contains("ARCA") && !roomName.Contains("INFO"))
                return false;

            // filter the training room and Imperial Garden and West Lake
            if (roomName.Contains("Training") || roomName.Contains("Imperial Garden") || roomName.Contains("Westlake"))
                return false;

            return true;
        }

        public static List<string> GetFavorMeetingRooms()
        {
            List<string> favorMeetingRooms = new List<string>();
            if (!File.Exists("FavorRoom.txt"))
                return favorMeetingRooms;
            using (StreamReader sr = File.OpenText("FavorRoom.txt"))
            {
                while (!sr.EndOfStream)
                {
                    string favorRoom = sr.ReadLine();
                    if (string.IsNullOrEmpty(favorRoom.Trim()))
                        continue;
                    favorMeetingRooms.Add(favorRoom);
                }
            }
            return favorMeetingRooms;
        }

        public static void SaveFavorMeetingRooms(List<string> favorRooms)
        {
            StringBuilder sbFavorRooms = new StringBuilder();
            foreach (string favorRoom in favorRooms)
            {
                sbFavorRooms.AppendLine(favorRoom);
            }
            sbFavorRooms.AppendLine();

            File.WriteAllText("FavorRoom.txt", sbFavorRooms.ToString(), Encoding.UTF8);

        }
    }
}
